import json

class Device(object):
    class SupportDevice():
        def __init__(self):
            self.deviceName:list[str] = []
            self.deviceDisplayName = ""
            self.deviceWindow = ""
            self.deviceIcon = ""
            self.deviceBinName = ""

    class SupportChiotDevice(SupportDevice):
        def __init__(self):
            super().__init__()
            self.deviceEncrypt = False

    class SupportAndlinkDevice(SupportDevice):
        def __init__(self):
            super().__init__()
            self.deviceType = ""

    #类变量
    s_ChiotDeviceList:list[SupportChiotDevice] = []
    s_AndlinkDeviceList:list[SupportAndlinkDevice] = []

    def __init__(self, ip, *args):
        self._IP = ip
        self._DisplayName = args[0] if len(args) >= 1 else "未知设备"
        self._MAC = args[1] if len(args) >= 2 else ""

    def GetIP(self):
        return self._IP

    def GetDisplayName(self):
        return self._DisplayName

    def GetMAC(self):
        return self._MAC

    def InitSupportDeviceList(jsonStr):
        Device.s_ChiotDeviceList.clear()
        Device.s_AndlinkDeviceList.clear()

        doc = json.loads(jsonStr)
        if (json == None):
            return False

        if (not "Chiot" in doc) or (not isinstance(doc["Chiot"], list)):
            return False
        
        for ChiotDeviceObj in doc["Chiot"]:
            if (not "deviceName" in ChiotDeviceObj or 
                not "deviceDisplayName" in ChiotDeviceObj or not isinstance(ChiotDeviceObj["deviceDisplayName"], str) or 
                not "deviceWindow" in ChiotDeviceObj or not isinstance(ChiotDeviceObj["deviceWindow"], str)):
                return False

            scd = Device.SupportChiotDevice()
            if (isinstance(ChiotDeviceObj["deviceName"], str)):
                scd.deviceName.append(ChiotDeviceObj["deviceName"])
            else:
                scd.deviceName = ChiotDeviceObj["deviceName"]
            scd.deviceDisplayName = ChiotDeviceObj["deviceDisplayName"]
            scd.deviceWindow = ChiotDeviceObj["deviceWindow"]
            scd.deviceIcon = ChiotDeviceObj["deviceIcon"] if "deviceIcon" in ChiotDeviceObj else ""
            scd.deviceBinName = ChiotDeviceObj["deviceBinName"] if "deviceBinName" in ChiotDeviceObj else "" 
            scd.deviceEncrypt = ChiotDeviceObj["deviceEncrypt"] if "deviceEncrypt" in ChiotDeviceObj else False
            Device.s_ChiotDeviceList.append(scd)

        if (not "Andlink" in doc) or (not isinstance(doc["Andlink"], list)):
            return False

        for AndlinkDeviceListObj in doc["Andlink"]:
            if (not "deviceName" in AndlinkDeviceListObj or 
                not "deviceDisplayName" in AndlinkDeviceListObj or not isinstance(AndlinkDeviceListObj["deviceDisplayName"], str) or 
                not "deviceWindow" in AndlinkDeviceListObj or not isinstance(AndlinkDeviceListObj["deviceWindow"], str) or
                not "deviceType" in AndlinkDeviceListObj or not isinstance(AndlinkDeviceListObj["deviceType"], str)):
                return False

            sad = Device.SupportAndlinkDevice()
            if (isinstance(AndlinkDeviceListObj["deviceName"], str)):
                sad.deviceName.append(AndlinkDeviceListObj["deviceName"])
            else:
                sad.deviceName = AndlinkDeviceListObj["deviceName"]
            sad.deviceDisplayName = AndlinkDeviceListObj["deviceDisplayName"]
            sad.deviceWindow = AndlinkDeviceListObj["deviceWindow"]
            sad.deviceIcon = AndlinkDeviceListObj["deviceIcon"] if "deviceIcon" in AndlinkDeviceListObj else ""
            sad.deviceBinName = AndlinkDeviceListObj["deviceBinName"] if "deviceBinName" in AndlinkDeviceListObj else ""
            sad.deviceType = AndlinkDeviceListObj["deviceType"]
            Device.s_AndlinkDeviceList.append(sad)

        return True

    def GetSupportChiotDeviceByDeviceName(deviceName):
        for chiotDevice in Device.s_ChiotDeviceList:
            if deviceName in chiotDevice.deviceName:
                return chiotDevice

        return None

    def GetSupportChiotDeviceByDisplayName(displayName):
        for chiotDevice in Device.s_ChiotDeviceList:
            if displayName == chiotDevice.deviceDisplayName:
                return chiotDevice

        return None

    def GetSupportAndlinkDeviceByDeviceName(deviceName):
        for andlinkDevice in Device.s_AndlinkDeviceList:
            if deviceName in andlinkDevice.deviceName:
                return andlinkDevice

        return None

    def GetSupportAndlinkDeviceByDisplayName(displayName):
        for andlinkDevice in Device.s_AndlinkDeviceList:
            if displayName == andlinkDevice.deviceDisplayName:
                return andlinkDevice

        return None

    def GetSupportAndlinkDeviceByDeviceType(deviceType):
        for andlinkDevice in Device.s_AndlinkDeviceList:
            if deviceType == andlinkDevice.deviceType:
                return andlinkDevice

        return None

    def GetSupportDeviceDisplayNameList():
        displayNameList = []
        for chiotDevice in Device.s_ChiotDeviceList:
            displayNameList.append(chiotDevice.deviceDisplayName)

        for andlinkDevice in Device.s_AndlinkDeviceList:
            displayNameList.append(andlinkDevice.deviceDisplayName)

        return displayNameList

class ChiotDevice(Device):
    def __initFromInfos(self, ip, infos:str):
        Device.__init__(self, ip)
        self.__CmdPort = 18000
        self.__LogPort = 18001

        slist = [x for x in infos.split('_') if x]
        if len(slist) > 5 and slist[0] == "DeviceOnline":
            self.__CmdPort = slist[1]
            self.__LogPort = slist[2]

            scd = Device.GetSupportChiotDeviceByDeviceName(slist[3].strip())
            self._DisplayName = scd.deviceDisplayName if not scd is None else "未知设备"
            self._MAC = slist[4].strip()

    def __initFromParams(self, ip, type, comPort, logPort, MAC):
        Device.__init__(self, ip, type, MAC)
        self.__CmdPort = comPort
        self.__LogPort = logPort

    def __init__(self, ip, *args):
        if len(args) == 1:
            self.__initFromInfos(ip, args[0])
        elif len(args) == 4:
            self.__initFromParams(ip, args[0], args[1], args[2], args[3])

    def getCmdPort(self):
        return self.__CmdPort

    def getLogPort(self):
        return self.__LogPort

class AndlinkDevice(Device):
    def __init__(self, ip, infos:str):
        super().__init__(ip)
        
        infos_temp = infos[infos.index("{")]
        doc = json.loads(infos_temp)
        if (json is None):
            return

        if ("deviceId" in doc and isinstance(doc["deviceId"], str)):
            slist = doc["deviceId"].split('-')
            if (slist.count() >= 3 and slist[0] == "CMCC"):
                self.m_MAC = slist[2].strip()

        if ("deviceType" in doc and isinstance(doc["deviceType"], str)):
            sad = Device.GetSupportAndlinkDeviceByDeviceType(doc["deviceType"])
            self._DisplayName = sad.deviceDisplayName if not sad is None else "未知设备"

    def __init__(self, ip, type, MAC):
        super().__init__(ip, type, MAC)

